package iPod;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class DataUtils {

    /**
     * Convert a Little Endian 4-byte array into an int.
     **/
    public static int littleEndianToInt(byte[] item) 
    {
    	return ByteBuffer.wrap(item).order(ByteOrder.LITTLE_ENDIAN).getInt();
    }


    /**
     * Convert an int to a Little Endian 4-byte array.
     */
    public static byte[] intToLittleEndian(int value) 
    {
		ByteBuffer bb = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN);
		bb.putInt(value);
		
		return bb.array();
    }


    /**
     * Convert a byte array into an int.
     **/
    public static int byteArrayToInt(byte[] b) 
    {
		int i = 0;
		for(int n=0; n < b.length; n++) {
		    i += ((int) b[n]) << (8 * (b.length - n - 1));
		}
	
		return i;
    }


    /**
     * Convert an int to a 4-Byte array.
     **/
    public static byte[] intTo4ByteArray(int i) 
    {
		ByteBuffer bb = ByteBuffer.allocate(4);
		bb.putInt(i);
	
		return bb.array();
    }


    /**
     * Convert an int to a 8-Byte array.
     **/
    public static byte[] intTo8ByteArray(int i) 
    {
		ByteBuffer bb = ByteBuffer.allocate(8);
		bb.putInt(i);
	
		return bb.array();
    }


    /**
     * Pad the given string with a null byte between each character, then
     * return it as a byte array.  The boolean tells us if we should write
     * a null byte in the first position or not.  true = first byte null,
     * false = second byte null.
     **/
    public static byte[] stringToBytesWithNulls(String s, boolean null_first) 
    {
		byte[] array = new byte[s.length() * 2];
	
		byte[] string = s.getBytes();
	
		for(int i=0; i < string.length; i++) {
		    if(null_first) {
			array[i*2] = 0x00;
			array[(i*2)+1] = string[i];
		    }
		    else {
			array[i*2] = string[i];
			array[(i*2)+1] = 0x00;
		    }
		}
	
		return array;
    }

    /**
     * Strip the null byte between each character in the given byte array.
     * The boolean tells us if we should expect the first byte to be null or not
     * true = first byte null, false = second byte null
     **/
    public static String stripNullBytes(byte[] array, boolean null_first) 
    {
		// NOTE: could this be done better/faster with bit shifing << >> ??
	
		byte[] string = new byte[array.length / 2];
	
		for(int i=0; i < string.length; i++)
		    if(null_first)
			string[i] = array[(i*2)+1];
		    else
			string[i] = array[(i*2)];
	
		return new String(string);
    }


    /**
     * Convert a byte array to it's hex representation as a String.
     * Nice for debugging.
     **/
    public static String byteArrayToHexString(byte in[]) 
    {
		byte ch = 0x00;
		int i = 0; 
	
		if (in == null || in.length <= 0)
		    return null;
	
		String pseudo[] = {"0", "1", "2",
				   "3", "4", "5", "6", "7", "8",
				   "9", "A", "B", "C", "D", "E",
				   "F"};
	
		StringBuffer out = new StringBuffer(in.length * 2);
	
		while (i < in.length) {
		    ch = (byte) (in[i] & 0xF0); // Strip off high nibble
		    ch = (byte) (ch >>> 4); // shift the bits down
		    ch = (byte) (ch & 0x0F); // must do this is high order bit is on!
		    out.append(pseudo[(int) ch]); // convert the nibble to a String
		    ch = (byte) (in[i] & 0x0F); // Strip off low nibble 
		    out.append(pseudo[(int) ch]); // convert the nibble to a String
	
		    i++;
		}
	
		String rslt = new String(out);
	
		return rslt;
    }    

}
